package main

import (
	"context"
	"estimate/logic"
	"estimate/pb"
	"fmt"
	"net"

	"github.com/go-redis/redis/v8"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"github.com/spf13/viper"
	"google.golang.org/grpc"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
)

// hello server

type server struct {
	pb.UnimplementedTrustServer
	r  *redis.Client
	db *gorm.DB
}

type TrustEstimateRo2 struct {
	DeviceId   string `json:"deviceId"`
	AppId      string `json:"appId"`
	Level      string `json:"level"`
	Agreement  string `json:"agreement"`
	TargetIp   string `json:"targetIp"`
	TargetPort string `json:"targetPort"`
	UserId     string `json:"userId"`
}

func (s *server) TrustEstimate(ctx context.Context, in *pb.EstimateRequest) (*pb.EstimateResponse, error) {
	req := &logic.TrustEstimateRo2{}
	//	{"deviceId": "userMac-860","appId": "456","targetIp": "127.0.0.1","targetPort": "1","status": "1","userId":"user-860","level":"","agreement":""}
	//	req.DeviceId = "userMac-860"
	// req.DeviceId = "userMac-86"
	// req.AppId = "456"
	// req.TargetIp = "127.0.0.1"
	// req.TargetPort = "1"
	// req.UserId = "user-860"
	req.DeviceId = in.DeviceId
	req.AppId = in.AppId
	req.TargetIp = in.TargetIp
	req.TargetPort = in.TargetPort
	req.UserId = in.UserId
	resp, err := logic.TrustEstimate2(req, s.r, s.db)
	if err != nil {
		return nil, err
	}
	return &pb.EstimateResponse{Status: resp.Status, Msg: resp.Msg, Code: resp.Code}, nil
}

func ConnectMySQL(host, port, user, pass, dbname string) (*gorm.DB, error) {
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		user, pass, host, port, dbname)
	//	&gorm.Config{NamingStrategy: schema.NamingStrategy{SingularTable: true}
	return gorm.Open(mysql.Open(dsn), &gorm.Config{NamingStrategy: schema.NamingStrategy{SingularTable: true}})
}

func configInit() (*gorm.DB, *redis.Client, net.Listener) {
	// 读取配置文件
	viper.SetConfigFile("config/config.ini")
	err := viper.ReadInConfig()
	if err != nil {
		panic(fmt.Errorf("配置文件读取失败: %s", err))
	}
	// 连接MySQL
	mysqlCfg := viper.GetStringMapString("mysql")
	db, err := ConnectMySQL(mysqlCfg["host"], mysqlCfg["port"], mysqlCfg["username"], mysqlCfg["password"], mysqlCfg["database"])
	if err != nil {
		panic("failed to connect to MySQL database")
	}
	//db.SingularTable(true)

	// 连接Redis
	redisCfg := viper.GetStringMapString("redis")
	rdb := redis.NewClient(&redis.Options{
		Addr:     fmt.Sprintf("%s:%s", redisCfg["host"], redisCfg["port"]),
		Password: redisCfg["password"],
		DB:       viper.GetInt("redis.database"),
		PoolSize: viper.GetInt("redis.pool_size"),
	})
	if rdb == nil {
		panic("failed to connect to MySQL redis")
	}

	// 监听本地的8972端口
	lis, err := net.Listen("tcp", ":"+viper.GetString("grpc.port"))
	if err != nil {
		fmt.Printf("failed to listen: %v", err)
		return nil, nil, nil
	}
	return db, rdb, lis
}

func main() {
	//初始化mysql，redis
	db, r, lis := configInit()
	fmt.Println("trust server runing")

	localServer := &server{}
	localServer.r = r
	localServer.db = db                    //初始化资源
	s := grpc.NewServer()                  // 创建gRPC服务器
	pb.RegisterTrustServer(s, localServer) // 在gRPC服务端注册服务
	// 启动服务
	err := s.Serve(lis)
	if err != nil {
		fmt.Printf("failed to serve: %v", err)
		return
	}

}
